package org.jample.velocity;

import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

/**
 * This Utility class process the template string , merge the parameter into it.
 * it only support velocity el
 * 
 * @author eccicce
 * @version $Revision: $
 */
public final class TemplateUtil {
    /** Revision of the class */
    public static final String _REV_ID_ = "$Revision: $";

    private TemplateUtil() {

    }

    /**
     * parse template string , merge parameter into it
     * 
     * @param str
     *            template string
     * @param parameter
     *            replace parameters
     * @return
     */
    public static <V> String parse(String str, Map<String, V> parameter) {
        if (parameter == null) {
            return str;
        }
        VelocityContext context = new VelocityContext(processParameter(parameter));
        try {
            StringWriter sw = new StringWriter();
            Velocity.evaluate(context, sw, "", str);
            return sw.toString();
        } catch (Exception e) {
            throw new RuntimeException("Parse template string failure. " + e.getMessage(), e);
        }
    }

    /**
     * Simple replace the token in template string
     * 
     * @param str
     *            template string
     * @param parameter
     *            replace parameter set
     * @return
     */
    public static String replaceToken(String str, Map<String, String> parameter) {
        if (parameter == null) {
            return str;
        }
        for (Map.Entry<String, String> e : parameter.entrySet()) {
            str = StringUtils.replace(str, "$" + e.getKey(), e.getValue());
        }
        return str;
    }

    /**
     * parse template string , merge parameter into it only one parameter are
     * allowed here.
     * 
     * @param str
     *            template string
     * @return
     */
    public static String findConitionContent(String str) {
        int startPosition = str.indexOf("#if");
        int endPosition = str.indexOf("#end");
        if (startPosition >= 0 && endPosition > 1) {
            int start = str.indexOf(')', startPosition) + 1;
            return str.substring(start, endPosition);
        }
        return null;
    }

    /**
     * convert empty string to null, and split the string to arrayList if need
     *
     * @param parameter
     * @return
     */
    public static <V> Map<String, V> processParameter(Map<String, V> parameter) {
        if (parameter == null) {
            return null;
        }

        Map<String, V> temp = new HashMap<String, V>();
        for (Map.Entry<String, V> e : parameter.entrySet()) {
            String value = e.getValue() == null ? "" : String.valueOf(e.getValue());
            if (!StringUtils.isBlank(value)) {
                temp.put(e.getKey(), e.getValue());
            }
        }

        return temp;
    }

    static {
        try {
            Velocity.init();
        } catch (Exception e) {
            throw new RuntimeException("Exception occurs while initialzie the velociy: " + e.getMessage(), e);
        }
    }
}
